/**
 * Copyright © 2019 eqxiu.com 北京中网易企秀科技有限公司  All rights reserved.
 */
package com.siping.数据库.pool;

import org.apache.commons.lang.math.RandomUtils;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

import java.sql.Connection;
import java.sql.DriverManager;

/**
 * @author YangXu
 * @date 2022/2/28
 * @description:
 */
public class PoolTest {

    public static void main(String[] args) {
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        MyPooledFactory factory = new MyPooledFactory();
        GenericObjectPool<Connection> pool = new GenericObjectPool<>(factory, config);
        pool.setMinIdle(2);
        pool.setMaxIdle(3);
        pool.setMaxTotal(3);
        try {
            for (int i = 0; i < 5; i++) {
                new Thread(() -> {
                    try {
                        Connection connection = pool.borrowObject(30000);
                        System.out.println(Thread.currentThread().getName() + "拿到连接对象:" + connection);
                        connection.prepareStatement("select * from biz_material");
                        int time = RandomUtils.nextInt(3000);
                        Thread.sleep(time);
                        System.out.println(Thread.currentThread().getName() + " -> 执行查询，耗时：" + time);
                        pool.returnObject(connection);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }, "t-" + i).start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static class MyPooledFactory implements PooledObjectFactory<Connection> {

        private static final long VALIDATION_WAIT_IN_MILLIS = 1000;

        @Override
        public PooledObject<Connection> makeObject() throws Exception {
            long start = System.currentTimeMillis();
            Connection conn = null;
            try {
                Class.forName("com.mysql.jdbc.Driver");
                conn = DriverManager.getConnection("jdbc:mysql://150.158.41.14:3306/test_db?useUnicode=true&characterEncoding=UTF-8&useSSL=false",
                        "baibaox", "baibaox2021_yx@");
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("连接失败");
            }
            System.out.println(Thread.currentThread().getName() + "创建对象：" + conn + "耗时：" + (System.currentTimeMillis() - start));
            return new DefaultPooledObject<>(conn);
        }

        @Override
        public void destroyObject(final PooledObject<Connection> pooledObject) throws Exception {
            System.out.println(Thread.currentThread().getName() +"销毁对象：" + pooledObject.getCreateTime());
        }

        @Override
        public boolean validateObject(final PooledObject<Connection> pooledObject) {
            System.out.println(Thread.currentThread().getName() +"校验对象");
            try {
                Thread.sleep(VALIDATION_WAIT_IN_MILLIS);
            } catch (final InterruptedException e) {
                Thread.interrupted();
            }
            return false;
        }

        @Override
        public void activateObject(final PooledObject<Connection> pooledObject) throws Exception {
            // 在借用一个对象时调用
            System.out.println(Thread.currentThread().getName() +"借用对象：" + pooledObject.getObject());
        }

        @Override
        public void passivateObject(final PooledObject<Connection> pooledObject) throws Exception {
            // 归还对象时调用
            System.out.println(Thread.currentThread().getName() +"归还对象了：" + pooledObject.getObject());
        }
    }
}
